﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace modul3
{
    [Serializable]
    public class SysIndex
    {

        #region privatne atributy
        private int piDalsieIdIndexu = 1;
        private List<SysIndexMy> paIndexy = new List<SysIndexMy>();
        #endregion


        #region properties
        public int iDalsieIdIndexu
        {
            get { return piDalsieIdIndexu; }
            set { piDalsieIdIndexu = value; }
        }

        /// <summary>
        /// zoznam uplne vsetkych indexov
        /// </summary>
        public List<SysIndexMy> aIndexy
        {
            get { return paIndexy; }
            set { paIndexy = value; }
        }
        #endregion


        #region metody
        /// <summary>
        /// vytvori index
        /// </summary>
        /// <param name="pa_sNazov">nazov indexu</param>
        /// <param name="pa_kTyp">typ indexu</param>
        /// <param name="pa_bUnique">unikatny index</param>
        /// <param name="pa_aColumns">List(int) obsahujuci cisla stlpcov </param>
        /// <returns></returns>
        public kkRetValue createIdx(string pa_sNazov, SysIndexTypes pa_kTyp, bool pa_bUnique, List<int> pa_aColumns)
        {
            kkRetValue vystup = kkRetValue.Chyba;
            SysIndexMy novyIndex = new SysIndexMy(pa_sNazov, pa_kTyp, pa_bUnique, pa_aColumns, iDalsieIdIndexu);
            // skontrolujem ci taky moze byt
            bool pridat = true;
            if (novyIndex.aColumns.Count == 0)
            {
                pridat = false;
                vystup = kkRetValue.ZiadenStlpec;
            }
            else if (pa_bUnique)
            {
                //prejdenie vsetkych indexov a zistenie, ci taky existuje (s rovnakymi stlpcami)
                foreach (SysIndexMy indexCyklus in aIndexy)
                {
                    if (indexCyklus.aColumns.Count == novyIndex.aColumns.Count)
                    {
                        int pocetNajdeni = 0;
                        foreach (int columnCyklus in novyIndex.aColumns)
                        {
                            if (indexCyklus.aColumns.Contains(columnCyklus))
                            {
                                pocetNajdeni++;
                            }
                        }
                        if (pocetNajdeni == novyIndex.aColumns.Count)
                        {
                            pridat = false;
                            vystup = kkRetValue.Neunikatne;
                        }
                    }
                }
            }
            if (pridat)
            {
                aIndexy.Add(novyIndex);
                iDalsieIdIndexu++;
                vystup = kkRetValue.OK;
                Save();
            }
            return vystup;
        }


        /// <summary>
        /// zrusi konkretny index
        /// </summary>
        /// <param name="pa_cRusenyIndex">ruseny index</param>
        /// <returns>bool, ci bol index zruseny</returns>
        private kkRetValue dropIdx(SysIndexMy pa_cRusenyIndex)
        {
            kkRetValue vystup = kkRetValue.Chyba;
            if (aIndexy.Remove(pa_cRusenyIndex))
            {
                vystup = kkRetValue.OK;
                Save();
            }
            else
            {
                vystup = kkRetValue.Nenajdeny;
            }
            return vystup;
        }


        public kkRetValue dropIdx(int pa_iRusenyIndex)
        {
            return dropIdx(getIndexObject(pa_iRusenyIndex));
        }

        /// <summary>
        /// dropne vsetky indexy zo stlpca
        /// </summary>
        public void dropAllFromColumn(int pa_iColumn)
        {
            int index;
            while ((index = isInIdx(pa_iColumn)) != 0)
            {
                if (dropIdx(index) != kkRetValue.OK)
                {
                    // ked sa nepodari vymazat index
                    throw new Exception("chyba");
                }
            }
        }


        private SysIndexMy getIndexObject(int pa_iId)
        {
            foreach (SysIndexMy indexCyklus in aIndexy)
            {
                if (indexCyklus.iId == pa_iId)
                {
                    return indexCyklus;
                }
            }
            return null;
        }


        /// <summary>
        /// Zisti, ci existuje nejaky index nad stlpcom. 
        /// Ak nie, tak vrati 0, inak vrati id prveho najdeneho indexu
        /// </summary>
        /// <param name="pa_iColumn">id stlpca, ktory zistujeme</param>
        /// <returns></returns>
        public int isInIdx(int pa_iColumn)
        {
            foreach (SysIndexMy indexCyklus in aIndexy)
            {
                foreach (int columnCyklus in indexCyklus.aColumns)
                {
                    if (columnCyklus == pa_iColumn)
                    {
                        return indexCyklus.iId;
                    }
                }
            }
            return 0;
        }


        /// <summary>
        /// vrati indexy daneho stlpca. Konkretne pole id-ciek indexov nad danym stlpcom
        /// </summary>
        /// <returns></returns>
        public List<int> listIdx(int pa_iColumn)
        {
            List<int> vystup = new List<int>();
            foreach (SysIndexMy indexCyklus in aIndexy)
            {
                foreach (int columnCyklus in indexCyklus.aColumns)
                {
                    if (columnCyklus == pa_iColumn)
                    {
                        vystup.Add(indexCyklus.iId);
                    }
                }
            }
            return vystup;
        }

        public void Save()
        {
            FunctionsModule3.StoreSysIndex(this);
        }
        #endregion
    }
}
